<template>
  <div>
    <el-dialog v-if="enable" :visible.sync="enable" title="网站配置" :close-on-click-modal="false">
      <div v-if="!vhost.isAdmootCreated">
        <codemirror ref="editRaw" v-model="vhost.raw" :options="editorRawOptions" class="code"></codemirror>
      </div>
      <el-form ref="form" label-width="100px" v-if="vhost.isAdmootCreated">
        <el-tabs value="general" tab-position="left" @tab-click="actionHandleConfigTabClicked">
          <el-tab-pane label="通用" name="general">
            <el-form-item label="说明">
              <el-input v-model="vhost.comment"></el-input>
            </el-form-item>
            <el-form-item label="访问日志">
              <el-input v-model="vhost.accesslog"></el-input>
            </el-form-item>
            <el-form-item label="错误日志">
              <el-input v-model="vhost.errorlog"></el-input>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane label="目录" name="directory">
            <el-form-item label="内容目录">
              <el-input v-model="vhost.documentRoot"></el-input>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane label="SSL" name="ssl">
            <el-form-item label="开启">
              <el-checkbox v-model="vhost.sslEnable"></el-checkbox>
            </el-form-item>
            <el-form-item label="证书路径">
              <el-input v-model="vhost.sslCertificateFile"></el-input>
            </el-form-item>
            <el-form-item label="证书私钥路径">
              <el-input v-model="vhost.sslCertificateKeyFile"></el-input>
            </el-form-item>
            <el-form-item label="证书链路径">
              <el-input v-model="vhost.sslCertificateChainFile"></el-input>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane label="反向代理" name="proxy">
            <div v-for="(proxcy, index) in vhost.proxies" :key="index">
              <el-form-item label="路径">
                <el-input v-model="proxcy.dir" @input="actionForceUpdate"></el-input>
              </el-form-item>
              <el-form-item label="目标">
                <el-input v-model="proxcy.target" @input="actionForceUpdate"></el-input>
              </el-form-item>
              <div style="text-align:right;">
                <el-button size="mini" @click="actionProxyDelete(index)">删除</el-button>
              </div>
              <el-divider></el-divider>
            </div>
            <el-button size="mini" @click="actionProxyAdd">添加</el-button>
          </el-tab-pane>
          <el-tab-pane label="伪静态" name="rewrite">
            <codemirror ref="editRewrite" v-model="vhost.rewriteRules" :options="editorOptions" class="code"></codemirror>
          </el-tab-pane>
          <el-tab-pane label="预览" name="config-raw">
            <codemirror ref="editConfigRaw" :value="configRaw" :options="editorOptions" class="code"></codemirror>
          </el-tab-pane>
        </el-tabs>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="enable = false">取 消</el-button>
        <el-button type="primary" @click="actionSave">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import "codemirror/theme/ambiance.css";
require("codemirror/mode/javascript/javascript");
require("codemirror/mode/shell/shell.js");
import yaml from 'js-yaml'
import Common from '../../utils/Common.js'
export default {
    name : 'ApacheDialogVirtualHostConfig',
    components : {
        codemirror,
    },
    data() {
        return {
            counter : 0,
            enable : false,
            vhost : {},
            vhostOriginal : null,
            editorOptions : {
                autoRefresh : true,
                mode:'text/javascript',
                theme: 'ambiance',
                readOnly:false,
            },
            editorRawOptions : {
                mode:'javascript',
                theme: 'ambiance',
                readOnly:false,
                lineNumbers:true,
                lineWrapping:true,
                autofocus:true,
            },
        };
    },
    computed : {
        configRaw() {
            this.counter ++;
            return this.gernerateConfigContent(this.vhost);
        }
    },
    methods : {
        /** */
        async open( vhost ) {
            this.enable = true;
            this.vhost = await this.parseVirtualHostFile(vhost.file);
            if ( undefined != this.vhost.rewriteRules ) {
                this.vhost.rewriteRules = this.vhost.rewriteRules.join("\n");
            }
            this.vhostOriginal = JSON.parse(JSON.stringify(this.vhost));
        },

         /** 解析配置文件 */
        async parseVirtualHostFile( filepath ) {
            let server = this.$store.getters.serverCurrent;
            let content = await server.fileGetContent(`/etc/apache2/sites-available/${filepath}`);
            let lines = content.trim().split('\n');
            console.log(lines);

            let configContent = [];
            let isConfigStarted = false;
            for ( let i=0; i<lines.length; i++ ) {
                if ( '# ADMOOT APACHE VIRTUALHOST CONFIG START' == lines[i].trim() ) {
                    isConfigStarted = true;
                    continue;
                }
                if ( '# ADMOOT APACHE VIRTUALHOST CONFIG END' == lines[i].trim() ) {
                    isConfigStarted = false;
                    break;
                }
                configContent.push(lines[i].substr(2));
            }
            configContent.push('');
            configContent = configContent.join("\n");

            let vhost = yaml.load(configContent);
            if ( 'string' == typeof(vhost) ) {
                vhost = {};
                vhost.isAdmootCreated = false;
            } else {
                vhost.isAdmootCreated = true;
            }
            vhost.file = filepath;
            vhost.raw = content;
            return vhost;
        },

        /** 生成配置文件内容 */
        gernerateConfigContent(config) {
            let conf = [];
            let comDoc = {};
            comDoc.comment = config.comment

            conf.push(`<VirtualHost *:80>`);
            conf.push(`  ServerName ${config.serverName}`);
            comDoc.serverName = config.serverName
            
            /** General */
            if ( !Common.isVarEmpty(config.accesslog) ) {
                comDoc.accesslog = config.accesslog;
                conf.push(`  CustomLog "${config.accesslog}" combined`);
            }
            if ( !Common.isVarEmpty(config.errorlog) ) {
                comDoc.errorlog = config.errorlog;
                conf.push(`  ErrorLog "${config.errorlog}"`);
            }
            
            /** Directory */
            if (  !Common.isVarEmpty(config.documentRoot) ) {
                comDoc.documentRoot = config.documentRoot;
                conf.push(`  DocumentRoot "${config.documentRoot.trim()}"`);
            }

            /** SSL */
            if ( !Common.isVarEmpty(config.sslEnable) && true == config.sslEnable ) {
                comDoc.sslEnable = true;
                comDoc.sslEnable = config.sslCertificateFile;
                comDoc.sslEnable = config.sslCertificateKeyFile;
                comDoc.sslEnable = config.sslCertificateChainFile;
                conf.push(`  SSLEngine on`);
                conf.push(`  SSLCertificateFile ${config.sslCertificateFile}`);
                conf.push(`  SSLCertificateKeyFile ${config.sslCertificateKeyFile}`);
                conf.push(`  SSLCertificateChainFile ${config.sslCertificateChainFile}`);
            } else {
                comDoc.sslEnable = false;
            }

            /** Proxy */
            if ( !Common.isVarEmpty(config.proxies) ) {
                comDoc.proxies = [];
                for ( let i=0; i<config.proxies.length; i++ ) {
                    let proxy = config.proxies[i];
                    if ( Common.isVarEmpty(proxy.dir) || Common.isVarEmpty(proxy.target) ) {
                        continue;
                    }
                    comDoc.proxies.push(proxy);
                    conf.push(`  ProxyPass ${proxy.dir} ${proxy.target}`);
                    conf.push(`  ProxyPassReverse ${proxy.dir} ${proxy.target}`);
                }
            }

            /** Rewrite */
            if ( !Common.isVarEmpty(config.rewriteRules) ) {
                let rules = config.rewriteRules.trim().split("\n");
                comDoc.rewriteRules = [];
                for ( let i=0; i<rules.length; i++ ) {
                    comDoc.rewriteRules.push(rules[i]);
                    conf.push(`  ${rules[i]}`);
                }
            }

            conf.push(`</VirtualHost>`);

            comDoc = yaml.dump(comDoc).trim();
            comDoc = comDoc.split("\n");
            
            let vhost = [];
            vhost.push('# ADMOOT APACHE VIRTUALHOST CONFIG START');
            for ( let i=0; i<comDoc.length; i++ ) {
                vhost.push(`# ${comDoc[i]}`);
            }
            vhost.push('# ADMOOT APACHE VIRTUALHOST CONFIG END');
            vhost = vhost.concat(conf);
            return vhost.join("\n");
        },

        /** 添加代理 */
        actionProxyAdd() {
            if ( undefined == this.vhost.proxies ) {
                this.vhost.proxies = [];
            }
            this.vhost.proxies.push({dir:'',target:''});

            this.counter ++;
            this.$forceUpdate();
        },

        /** 删除代理 */
        actionProxyDelete(index) {
            this.counter ++;
            this.vhost.proxies.splice(index,1)
            this.$forceUpdate();
        },

        /** 保存配置 */
        async actionSave() {
            if ( this.vhost.isAdmootCreated ) {
                let conf = this.gernerateConfigContent(this.vhost);
                let oriConf = this.gernerateConfigContent(this.vhostOriginal);
                if ( conf != oriConf ) {
                    let server = this.$store.getters.serverCurrent;
                    server.filePutContent(`/etc/apache2/sites-available/${this.vhost.file}`, conf);
                    await server.exec('systemctl restart apache2');
                }
            } else {
                let server = this.$store.getters.serverCurrent;
                server.filePutContent(`/etc/apache2/sites-available/${this.vhost.file}`, this.vhost.raw);
                await server.exec('systemctl restart apache2');
            }

            this.$emit('update');
            this.enable = false;
        },

        /** 强制更新 */
        actionForceUpdate() {
            this.counter ++;
            this.$forceUpdate();
        },

        // tab 标签被点击
        actionHandleConfigTabClicked( tab ) {
            let $this = this;
            if ( 'rewrite' == tab.name ) {
                setTimeout(function() {
                    $this.$refs.editRewrite.codemirror.refresh();
                    $this.$refs.editRewrite.codemirror.focus();
                }, 50);
            } else if ( 'config-raw' == tab.name ) {
                setTimeout(function() {
                    $this.$refs.editConfigRaw.codemirror.refresh();
                    $this.$refs.editConfigRaw.codemirror.focus();
                }, 50);
            }
        },
    },
}
</script>